//
//  BaseDataChartViewModel.swift
//  MoyoungHome
//
//  Created by 李然 on 2022/9/15.
//

import UIKit
import Charts
import RxCocoa
import RxSwift
import SwiftDate
import MYModule

open class BaseDataChartViewModel:ViewModel, ViewModelType {
    
    public struct Input{
        public let selectIndex:PublishSubject<Int>
        
        public init(selectIndex:PublishSubject<Int>) {
            self.selectIndex = selectIndex
        }
    }
     
    public struct Output{
        public let dataString:Driver<String>
        public let timeString:Driver<String>
    }
      
    public let date:Date
    public let defaultValue:Double
    public let dataSource:[Double]
    public let chartType:DataChartType

    public var sliderEnd = PublishSubject<Bool>()
    
    public init(date:Date,
         defaultValue:Double,
         dataSource:[Double],
         chartType:DataChartType){
        
        self.date = date
        self.defaultValue = defaultValue
        self.dataSource = dataSource
        self.chartType = chartType
        super.init()
    }
    
    public func transform(input: Input) -> Output {
        
        let dataString = BehaviorRelay<String>(value: "")
        let timeString = BehaviorRelay<String>(value: "")
        
        input.selectIndex
            .asObservable()
            .subscribe(onNext:{ [weak self] selectIndex in
                guard let `self` = self else { return }
                
                var selectDate:Date!
                switch self.chartType {
                case .day:
                    selectDate = self.date.dateAtStartOf(.day) + (30 * (selectIndex + 1)).minutes
                case .week:
                    selectDate = self.date.dateAtStartOf(.weekOfMonth) + selectIndex.days
                case .month:
                    selectDate = self.date.dateAtStartOf(.month) + selectIndex.days
                case .custom:
                    selectDate = self.getCustomSelectDate(selectIndex)
                }
                
                let selectTimeString = self.getSelectedTimeString(with: selectDate)
                let selectDataString = self.getSelectedDataString(with: selectIndex)
                
                dataString.accept(selectDataString)
                timeString.accept(selectTimeString)
                
        }).disposed(by: rx.disposeBag)
        
        dataString.accept(self.getDefaultDataString())
        timeString.accept(self.getDefaultTimeString())
        
        
        sliderEnd.subscribe(onNext:{ _ in
            DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                
                dataString.accept(self.getDefaultDataString())
                timeString.accept(self.getDefaultTimeString())
                
            }
        }).disposed(by: rx.disposeBag)
        
        
        return Output(dataString: dataString.asDriver(onErrorJustReturn: ""),
                      timeString: timeString.asDriver(onErrorJustReturn: ""))
        
    }
    
    open func getCustomSelectDate(_ selectIndex:Int) -> Date {
        return self.date + selectIndex.minutes
    }
    
    /// 默认数据
    open func getDefaultDataString() -> String{
        return defaultValue == 0 ? "--" : String(Int(defaultValue))
    }
    

    /// 转换选择的数据
    open func getSelectedDataString(with index:Int) -> String{
        let count = self.dataSource.count > index ? self.dataSource[index] : 0
        return String(Int(count))
    }
    
    /// 默认时间
    open func getDefaultTimeString() -> String{
        switch chartType {
        case .day:
            return date.localString
        case .week:
            let startDate = date - 6.days
            return Date.localRangeString(start: startDate, end: date)
        case .month:
            return date.localMonthRangeString
        case .custom:
            return date.localString
        }
    }
    
    /// 转换选择的时间
    open func getSelectedTimeString(with date:Date) -> String {
        
        switch chartType {
        case .day:
            return date.localString
        case .week:
            let startDate = date - 6.days
            return Date.localRangeString(start: startDate, end: date)
        case .month:
            return date.localMonthRangeString
        case .custom:
            return date.localString
        }
 
    }
    
    /// 获取x轴的格式器
    open func getXAxisValueFotmatter() ->IAxisValueFormatter{
        switch chartType {
        case .day: return DayAxisValueFormatter()
        case .custom: return DayAxisValueFormatter()
        case .week: return WeekAxisValueFormatter()
        case .month: return MonthAxisValueFormatter(date: date)
        }
    }

    /// 获取x轴的数量
    open func getBarCount() -> Int{
        switch self.chartType{
        case .day: return 48
        case .custom: return self.dataSource.count
        case .week: return 7
        case .month: return self.date.monthDays
        }
    }
    
    /// 获取最大值
    open func getBarMaxValue() -> Double{
        var maxValue:Double = 100
        if let tmpMax = self.dataSource.max(){
            maxValue = max(tmpMax, maxValue)
        }
        return maxValue
    }
    
    /// 获取最小值
    open func getBarMinValue() -> Double {
        
        switch self.chartType {
            
        case .day:
            return getBarMaxValue() / 20
        case .week:
            return getBarMaxValue() / 20
        case .month:
            return getBarMaxValue() / 20
        case .custom:
            return 0
        }
        
        
    }
    
    /// 获取单元字符串
    open func getUnitString() -> String{
        return ""
    }
}
